{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f35bbea3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Init Plugin\n",
      "Init Graph Optimizer\n",
      "Init Kernel\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0a8d0167",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Metal device set to: Apple M1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2021-10-09 20:32:01.030076: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:305] Could not identify NUMA node of platform GPU ID 0, defaulting to 0. Your kernel may not have been built with NUMA support.\n",
      "2021-10-09 20:32:01.030477: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:271] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 0 MB memory) -> physical PluggableDevice (device: 0, name: METAL, pci bus id: <undefined>)\n"
     ]
    }
   ],
   "source": [
    "v=tf.Variable(0.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a24cb46c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(v+1).numpy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9c20c8aa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=5.0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v.assign(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0768bd46",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=5.0>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "084b97ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Variable 'UnreadVariable' shape=() dtype=float32, numpy=6.0>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v.assign_add(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "7d0241e5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(), dtype=float32, numpy=6.0>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v.read_value()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92af5c0f",
   "metadata": {},
   "source": [
    "# 自动微分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "47f8781c",
   "metadata": {},
   "outputs": [],
   "source": [
    "w=tf.Variable([[2.0]])\n",
    "with tf.GradientTape() as t:\n",
    "    loss=w*w*w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d70b7b70",
   "metadata": {},
   "outputs": [],
   "source": [
    "grad=t.gradient(loss,w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "08718213",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[12.]], dtype=float32)>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "8d20a86e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(), dtype=float32, numpy=192.0>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w=tf.constant(8.0)\n",
    "with tf.GradientTape() as t:\n",
    "    t.watch(w)\n",
    "    loss=w*w*w\n",
    "grad=t.gradient(loss,w)\n",
    "grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "0a0e405b",
   "metadata": {},
   "outputs": [],
   "source": [
    "(train_images,train_labels),_=tf.keras.datasets.mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "5369cb50",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_images=tf.expand_dims(train_images,-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "25b2a294",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([60000, 28, 28, 1])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_images.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "2e3a8752",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_images=tf.cast(train_images/255,tf.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "6870670f",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_labels=tf.cast(train_labels,tf.int64)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "e4dd0c26",
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset=tf.data.Dataset.from_tensor_slices((train_images,train_labels))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "ce904b7d",
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset=dataset.shuffle(10000).batch(32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "849ab401",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<BatchDataset shapes: ((None, 28, 28, 1), (None,)), types: (tf.float32, tf.int64)>"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "9f49790e",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = tf.keras.models.Sequential(\n",
    "    [tf.keras.layers.Conv2D(16,[3,3],activation='relu',input_shape=(None,None,1)),\n",
    "     tf.keras.layers.Conv2D(32,[3,3],activation='relu'),\n",
    "     tf.keras.layers.GlobalMaxPooling2D(),\n",
    "     tf.keras.layers.Dense(10)\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "0cafc16d",
   "metadata": {},
   "outputs": [],
   "source": [
    "optimizer=tf.keras.optimizers.Adam()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "f079f38c",
   "metadata": {},
   "outputs": [],
   "source": [
    "loss_func=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "00bb3e8f",
   "metadata": {},
   "outputs": [],
   "source": [
    "features,labels = next(iter(dataset))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "7e38d954",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([32, 28, 28, 1])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "features.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "8728dd79",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(32,), dtype=int64, numpy=\n",
       "array([9, 4, 7, 7, 5, 7, 4, 4, 3, 9, 8, 1, 1, 9, 0, 5, 2, 3, 9, 1, 5, 4,\n",
       "       9, 7, 9, 1, 1, 7, 6, 8, 1, 4])>"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "4db4236a",
   "metadata": {},
   "outputs": [],
   "source": [
    "predictions=model(features)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "afc680c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(32, 10), dtype=float32, numpy=\n",
       "array([[ 8.08605999e-02, -7.31556937e-02, -2.36777082e-01,\n",
       "         1.99804246e-01, -4.73901629e-01,  1.45473078e-01,\n",
       "        -1.41611800e-01,  2.86107570e-01, -4.40029204e-02,\n",
       "         6.72076941e-02],\n",
       "       [ 1.08838469e-01, -6.32498413e-02, -2.41838455e-01,\n",
       "         1.84646755e-01, -4.57054704e-01,  1.35241538e-01,\n",
       "        -1.50534019e-01,  2.53985971e-01, -4.33716513e-02,\n",
       "         6.80527687e-02],\n",
       "       [ 1.12816729e-01, -2.04406828e-02, -2.98752636e-01,\n",
       "         2.04117253e-01, -4.54255372e-01,  1.54401898e-01,\n",
       "        -1.64825484e-01,  2.40671426e-01, -2.35077795e-02,\n",
       "         7.72263482e-02],\n",
       "       [ 1.24667086e-01, -2.79375743e-02, -2.44400412e-01,\n",
       "         1.89960763e-01, -4.49738175e-01,  1.37921020e-01,\n",
       "        -1.78734407e-01,  2.58229315e-01, -4.42720056e-02,\n",
       "         9.32911485e-02],\n",
       "       [ 6.77687898e-02, -5.78282960e-02, -2.83566177e-01,\n",
       "         1.90685421e-01, -4.48013097e-01,  1.53688818e-01,\n",
       "        -1.56252831e-01,  2.35999972e-01, -1.73128024e-02,\n",
       "         6.78051710e-02],\n",
       "       [ 1.10510290e-01, -2.55264196e-04, -3.08616459e-01,\n",
       "         2.09111720e-01, -4.22869712e-01,  1.57621488e-01,\n",
       "        -1.48587540e-01,  2.04880878e-01, -2.32940447e-02,\n",
       "         6.13311641e-02],\n",
       "       [ 1.33431107e-01, -3.42641510e-02, -2.17004240e-01,\n",
       "         1.96167037e-01, -4.48397547e-01,  1.51675969e-01,\n",
       "        -1.58299208e-01,  2.81509519e-01, -6.34223968e-02,\n",
       "         1.08915538e-01],\n",
       "       [ 1.32273406e-01, -1.18201654e-02, -2.37664774e-01,\n",
       "         1.88516796e-01, -4.46951449e-01,  1.44060016e-01,\n",
       "        -1.43040568e-01,  2.62686402e-01, -6.39765710e-02,\n",
       "         1.06775619e-01],\n",
       "       [ 1.07770108e-01, -6.70285001e-02, -2.59678841e-01,\n",
       "         1.86046228e-01, -4.72286671e-01,  1.44810468e-01,\n",
       "        -1.48246035e-01,  2.89044619e-01, -3.81242521e-02,\n",
       "         7.06350207e-02],\n",
       "       [ 1.19813576e-01, -6.26335740e-02, -2.50455678e-01,\n",
       "         1.93548664e-01, -4.73215967e-01,  1.50840566e-01,\n",
       "        -1.62110090e-01,  2.72449166e-01, -5.00572771e-02,\n",
       "         6.64896667e-02],\n",
       "       [ 9.40559208e-02, -3.18592153e-02, -2.47382298e-01,\n",
       "         1.75329238e-01, -4.47361350e-01,  1.49475530e-01,\n",
       "        -1.32828787e-01,  2.69437939e-01, -4.04099450e-02,\n",
       "         8.67913365e-02],\n",
       "       [ 1.01297468e-01, -4.69813049e-02, -2.02853277e-01,\n",
       "         1.51463628e-01, -3.92167330e-01,  1.27135903e-01,\n",
       "        -1.08192675e-01,  2.40856707e-01, -6.93790838e-02,\n",
       "         1.04844697e-01],\n",
       "       [ 1.23527750e-01, -5.13239056e-02, -2.75171876e-01,\n",
       "         2.06172436e-01, -4.44531560e-01,  1.40329406e-01,\n",
       "        -1.86191037e-01,  2.58915454e-01, -2.36244220e-02,\n",
       "         6.59248680e-02],\n",
       "       [ 7.30405077e-02, -6.26541749e-02, -2.63501018e-01,\n",
       "         1.80783033e-01, -4.02613610e-01,  1.60040572e-01,\n",
       "        -1.09043486e-01,  2.28166133e-01, -1.77935585e-02,\n",
       "         7.40124658e-02],\n",
       "       [ 8.42519924e-02, -2.64762621e-02, -2.70999670e-01,\n",
       "         2.07883462e-01, -4.09626186e-01,  1.68211743e-01,\n",
       "        -1.11300036e-01,  1.77013114e-01, -6.44484460e-02,\n",
       "         8.75293687e-02],\n",
       "       [ 1.08076066e-01, -8.26197211e-03, -3.20758253e-01,\n",
       "         2.16769770e-01, -4.98513728e-01,  1.64466679e-01,\n",
       "        -1.80973232e-01,  2.48180076e-01, -3.75473164e-02,\n",
       "         6.98843896e-02],\n",
       "       [ 1.05353065e-01, -4.30689380e-02, -2.77830511e-01,\n",
       "         2.37298876e-01, -4.91193980e-01,  1.50292799e-01,\n",
       "        -1.60476744e-01,  2.62974858e-01, -5.85849769e-02,\n",
       "         8.11020359e-02],\n",
       "       [ 8.74665976e-02, -6.77058473e-02, -2.99552023e-01,\n",
       "         1.95616096e-01, -4.98563826e-01,  1.60432041e-01,\n",
       "        -1.60447016e-01,  2.62163728e-01, -4.13751230e-02,\n",
       "         7.30081424e-02],\n",
       "       [ 1.21528171e-01, -2.13768091e-02, -2.58999676e-01,\n",
       "         1.88766256e-01, -4.47442710e-01,  1.41645342e-01,\n",
       "        -1.49463773e-01,  2.45898068e-01, -6.35036156e-02,\n",
       "         9.73198339e-02],\n",
       "       [ 8.62102807e-02, -3.43298838e-02, -2.27419659e-01,\n",
       "         1.47631139e-01, -3.89381707e-01,  1.47684917e-01,\n",
       "        -1.21951431e-01,  2.67059624e-01, -7.23398700e-02,\n",
       "         9.88879949e-02],\n",
       "       [ 4.48006988e-02, -4.69263829e-02, -3.36990833e-01,\n",
       "         2.03343526e-01, -5.05242944e-01,  1.47771806e-01,\n",
       "        -1.93889841e-01,  2.45073259e-01,  8.05618241e-03,\n",
       "         7.95070827e-02],\n",
       "       [ 1.18741103e-01, -1.98495071e-02, -2.52185643e-01,\n",
       "         1.94771007e-01, -4.43440646e-01,  1.55803859e-01,\n",
       "        -1.53188765e-01,  2.45012999e-01, -7.11610615e-02,\n",
       "         8.24486464e-02],\n",
       "       [ 9.30217430e-02, -5.52070551e-02, -2.62336463e-01,\n",
       "         2.01196447e-01, -4.70343292e-01,  1.62347451e-01,\n",
       "        -1.66260585e-01,  2.66669631e-01, -4.92262952e-02,\n",
       "         8.70861933e-02],\n",
       "       [ 9.98337343e-02, -1.42143518e-02, -2.72110105e-01,\n",
       "         1.81654036e-01, -4.51389879e-01,  1.78589135e-01,\n",
       "        -1.37997821e-01,  2.70863354e-01, -2.58516092e-02,\n",
       "         4.54254523e-02],\n",
       "       [ 8.99345949e-02, -3.85060310e-02, -3.07057500e-01,\n",
       "         2.08275869e-01, -4.18094426e-01,  1.61187664e-01,\n",
       "        -1.63338661e-01,  2.05605894e-01, -1.16712674e-02,\n",
       "         1.01084992e-01],\n",
       "       [ 7.79618770e-02, -3.74084301e-02, -2.41454527e-01,\n",
       "         1.87020615e-01, -4.25945729e-01,  1.57655835e-01,\n",
       "        -1.15425549e-01,  2.60850757e-01, -4.90539111e-02,\n",
       "         1.14734948e-01],\n",
       "       [ 9.63519290e-02, -9.89798922e-03, -1.55196071e-01,\n",
       "         1.28771305e-01, -3.31250459e-01,  1.33381158e-01,\n",
       "        -6.93091080e-02,  2.57661998e-01, -5.98885715e-02,\n",
       "         6.61176965e-02],\n",
       "       [ 1.14251062e-01, -4.55535501e-02, -2.23848298e-01,\n",
       "         1.79008290e-01, -4.47095811e-01,  1.27325088e-01,\n",
       "        -1.43263519e-01,  2.88989216e-01, -4.91212457e-02,\n",
       "         5.71871288e-02],\n",
       "       [ 9.48751643e-02, -3.95706445e-02, -2.57031202e-01,\n",
       "         1.85879052e-01, -4.76833940e-01,  1.42274067e-01,\n",
       "        -1.50347322e-01,  2.67978400e-01, -4.15186919e-02,\n",
       "         1.22556977e-01],\n",
       "       [ 5.63782714e-02, -6.29030988e-02, -2.41594121e-01,\n",
       "         1.89610451e-01, -4.52819705e-01,  1.62855342e-01,\n",
       "        -1.14246383e-01,  2.40831062e-01, -6.19832389e-02,\n",
       "         7.94379115e-02],\n",
       "       [ 9.36377048e-02, -1.60808954e-02, -1.43324554e-01,\n",
       "         1.19194090e-01, -2.83414394e-01,  1.35002106e-01,\n",
       "        -6.33817837e-02,  2.04074234e-01, -8.51515830e-02,\n",
       "         8.94758403e-02],\n",
       "       [ 1.23712830e-01, -1.40866740e-02, -2.46633962e-01,\n",
       "         1.72578931e-01, -4.35215682e-01,  1.47282749e-01,\n",
       "        -1.48948580e-01,  2.70847291e-01, -9.49855670e-02,\n",
       "         7.37132281e-02]], dtype=float32)>"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "4d258108",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(32,), dtype=int64, numpy=\n",
       "array([7, 7, 7, 7, 7, 3, 7, 7, 7, 7, 7, 7, 7, 7, 3, 7, 7, 7, 7, 7, 7, 7,\n",
       "       7, 7, 3, 7, 7, 7, 7, 7, 7, 7])>"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.argmax(predictions,axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "304235d1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: shape=(32,), dtype=int64, numpy=\n",
       "array([9, 4, 7, 7, 5, 7, 4, 4, 3, 9, 8, 1, 1, 9, 0, 5, 2, 3, 9, 1, 5, 4,\n",
       "       9, 7, 9, 1, 1, 7, 6, 8, 1, 4])>"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "labels"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7217cf1d",
   "metadata": {},
   "source": [
    "## 自定义训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "e3b82f18",
   "metadata": {},
   "outputs": [],
   "source": [
    "def loss(model,x,y):\n",
    "    y_=model(x)\n",
    "    return loss_func(y,y_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "bb89c882",
   "metadata": {},
   "outputs": [],
   "source": [
    "def train_step(model,images,labels):\n",
    "    with tf.GradientTape() as t:\n",
    "        loss_step=loss(model,images,labels)\n",
    "    grads=t.gradient(loss_step,model.trainable_variables)\n",
    "    optimizer.apply_gradients(zip(grads,model.trainable_variables))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "f6ad3644",
   "metadata": {},
   "outputs": [],
   "source": [
    "def train():\n",
    "    for epoch in range(10):\n",
    "        for (batch,(images,labels)) in enumerate(dataset):\n",
    "            train_step(model,images,labels)\n",
    "        print('Epoch{} is finished'.format(epoch))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "4bb133a2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch0 is finished\n",
      "Epoch1 is finished\n",
      "Epoch2 is finished\n",
      "Epoch3 is finished\n",
      "Epoch4 is finished\n",
      "Epoch5 is finished\n",
      "Epoch6 is finished\n",
      "Epoch7 is finished\n",
      "Epoch8 is finished\n",
      "Epoch9 is finished\n"
     ]
    }
   ],
   "source": [
    "train()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b1224f9",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
